Fix problem of can not create two or more vmx guest.
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 21 Jul 2005 14:15:35 +0000 (14:15 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 21 Jul 2005 14:15:35 +0000 (14:15 +0000)
The original gdb server patch will cause the new vmx guest break the=20
old one. This patch make the arch_set_guest_info modify the correct
vmcs and also skip modifying during  creating.

Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>^
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
xen/arch/x86/domain.c
xen/arch/x86/vmx_io.c
xen/arch/x86/vmx_vmcs.c
xen/include/asm-x86/vmx.h
xen/include/asm-x86/vmx_vmcs.h

index 609822d40ae0e653ecadbe12a740bb62c63f4ba1..d28e5683f7207bec301359b4f09ee7641a5d4484 100644 (file)
@@ -417,12 +417,12 @@ int arch_set_info_guest(
 
         /* Ensure real hardware interrupts are enabled. */
         v->arch.guest_context.user_regs.eflags |= EF_IE;
-    } else {
-        __vmwrite(GUEST_RFLAGS, v->arch.guest_context.user_regs.eflags);
-        if (v->arch.guest_context.user_regs.eflags & EF_TF)
-                __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
-        else 
-                __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+    }
+    else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
+    {
+        return modify_vmcs(
+            &v->arch.arch_vmx,
+            &v->arch.guest_context.user_regs);
     }
 
     if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
index 83e79d6bbad10b1e19237e8ac1f0aa37d5480a03..cbc88deb8ba569100da7a88af381d3028f0d830f 100644 (file)
 
 #ifdef CONFIG_VMX
 #if defined (__i386__)
-static void load_cpu_user_regs(struct cpu_user_regs *regs)
+void load_cpu_user_regs(struct cpu_user_regs *regs)
 { 
     /*
      * Write the guest register value into VMCS
      */
     __vmwrite(GUEST_SS_SELECTOR, regs->ss);
     __vmwrite(GUEST_RSP, regs->esp);
+
     __vmwrite(GUEST_RFLAGS, regs->eflags);
+    if (regs->eflags & EF_TF)
+        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+    else 
+        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
     __vmwrite(GUEST_RIP, regs->eip);
 }
@@ -175,11 +181,17 @@ static void set_reg_value (int size, int index, int seg, struct cpu_user_regs *r
     }
 }
 #else
-static void load_cpu_user_regs(struct cpu_user_regs *regs)
+void load_cpu_user_regs(struct cpu_user_regs *regs)
 {
     __vmwrite(GUEST_SS_SELECTOR, regs->ss);
     __vmwrite(GUEST_RSP, regs->rsp);
+
     __vmwrite(GUEST_RFLAGS, regs->rflags);
+    if (regs->rflags & EF_TF)
+        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+    else 
+        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+
     __vmwrite(GUEST_CS_SELECTOR, regs->cs);
     __vmwrite(GUEST_RIP, regs->rip);
 }
index a8a01c7808433ce898590509492f3ffeac0254f5..b7277e08c9bd575d241568b7d00675d6e0f24a9e 100644 (file)
@@ -453,6 +453,35 @@ int construct_vmcs(struct arch_vmx_struct *arch_vmx,
         return -EINVAL;         
     }
 
+    if (regs->eflags & EF_TF)
+        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+    else 
+        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
+
+    return 0;
+}
+
+/*
+ * modify guest eflags and execption bitmap for gdb
+ */
+int modify_vmcs(struct arch_vmx_struct *arch_vmx,
+                struct cpu_user_regs *regs)
+{
+    int error;
+    u64 vmcs_phys_ptr, old, old_phys_ptr;
+    vmcs_phys_ptr = (u64) virt_to_phys(arch_vmx->vmcs);
+
+    old_phys_ptr = virt_to_phys(&old);
+    __vmptrst(old_phys_ptr);
+    if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
+        printk("modify_vmcs: load_vmcs failed: VMCS = %lx\n",
+                (unsigned long) vmcs_phys_ptr);
+        return -EINVAL; 
+    }
+    load_cpu_user_regs(regs);
+
+    __vmptrld(old_phys_ptr);
+
     return 0;
 }
 
index 952bb01cfc4a9e69d8a9b101b04ddb00948778ea..36ef003de831546ed205637b06a7da5c62c3adc7 100644 (file)
@@ -447,4 +447,8 @@ static inline int iopacket_port(struct domain *d)
     return get_sp(d)->sp_global.eport;
 }
 
+/* Prototypes */
+void load_cpu_user_regs(struct cpu_user_regs *regs);
+void store_cpu_user_regs(struct cpu_user_regs *regs);
+
 #endif /* __ASM_X86_VMX_H__ */
index 65debd3f6e90542716c98e7884861d36a17ec224..93cdb48127cf4d63a60fb94b95faef6f0736e19e 100644 (file)
@@ -97,6 +97,8 @@ int  load_vmcs(struct arch_vmx_struct *, u64);
 int  store_vmcs(struct arch_vmx_struct *, u64);
 int  construct_vmcs(struct arch_vmx_struct *, struct cpu_user_regs *, 
                     struct vcpu_guest_context *, int);
+int modify_vmcs(struct arch_vmx_struct *arch_vmx,
+                struct cpu_user_regs *regs);
 
 #define VMCS_USE_HOST_ENV       1
 #define VMCS_USE_SEPARATE_ENV   0